/*
 * AhaProtocol.h
 *
 *  Created on: 2 avr. 2011
 *      Author: eric
 */

#ifndef AHAPROTOCOL_H_
#define AHAPROTOCOL_H_

#include <Arduino.h>         // include types & constants of Wiring core API
#include <CircularQueue.h>

#include "Can.h"

#define CID_PRI_HIGH   0x00
#define CID_PRI_LOW    0x01

#define CID_TYP_NV     0x00
#define CID_TYP_EM     0x01

#define CID_DIR_INPUT  0x00
#define CID_DIR_OUTPUT 0x01

#define CID_EM_PING             0x00
#define CID_EM_WHO_IS_UP        0x01
#define CID_EM_FIRMWARE_VERSION 0x02
#define CID_EM_RESET            0x03
#define CID_EM_NV_CFG           0x04
#define CID_EM_NEED_ID          0x05
#define CID_EM_SET_ID           0x06
#define CID_EM_NEED_CFG         0x07
#define CID_EM_START_CFG        0x08
#define CID_EM_SET_CFG          0x09
#define CID_EM_END_CFG          0x0A

#define CID_3b_MASK             0x7
#define CID_5b_MASK             0x1F
#define CID_7b_MASK             0x7F
#define CID_11b_MASK            0x7FF
#define CID_15b_MASK            0x7FFF

#define CID_PRI_SHIFT      28
#define CID_TYP_SHIFT      27
#define CID_DIR_SHIFT      15
#define CID_NODE_SRC_SHIFT 16
#define CID_NODE_DST_SHIFT 5
#define CID_NV_BND_SHIFT   0
#define CID_EM_SHIFT       0

class AhaProtocol {
private:
	static uint32_t const CID_PRI_MASK = 0x10000000;
	static uint32_t const CID_TYP_MASK = 0x8000000;
	static uint32_t const CID_DIR_MASK = 0x8000;
	static uint32_t const CID_NODE_SRC_MASK = 0x7FF0000;
	static uint32_t const CID_NODE_DST_MASK = 0xFFE0;
	static uint32_t const CID_NV_BND_MASK = 0x7FFF;
	static uint32_t const CID_EM_MASK = 0x1F;
public:
	static uint32_t const BROADCAST_NODE = 0x7FF;
    static uint32_t const MASTER_CFG_NODE = 0x00;


	typedef struct {
		uint8_t CidPri :1;
		uint8_t CidTyp :1;
		uint8_t CidDir :1;
		uint8_t CidEm :5;
		uint16_t CidNodeSrc;
		union {
			uint16_t CidNodeDst;
			uint16_t CidNvBnd;
		};
		uint8_t nbytes;
		uint8_t data[8];
	} AHA_MSG;
	void getAhaMessage(Can::CAN_MSG *canMsg, AhaProtocol::AHA_MSG *ahaMsg);
	void setCanMessage(Can::CAN_MSG *canMsg, AhaProtocol::AHA_MSG *ahaMsg);
	void sendEMNeedId(AhaProtocol::AHA_MSG *ahaMsg, byte *nodeID);
	void sendEMNeedCfg(AhaProtocol::AHA_MSG *ahaMsg, uint16_t nodeAdr);
};

#endif /* AHAPROTOCOL_H_ */
